let logger = require("pomelo-logger").getLogger(__filename);
let DateUtil = require("../../utils/dateUtil");
let activityCreator = require("../entities/activity").create;
let activityLoader = require("../entities/activity").loadFromDocument;

const HOT_ACTIVITY_CONFIG_KEY = "activityHotId";

let ActivityService = function (app) {
    this.app = app;
    this.activities = [];
    this.nextActivityId = 0;
    // this.activityHotId = 0;
};

ActivityService.prototype.initialize = function () {
    let activityDao = this.app.get("activityDao");
    let maxActivityId = 0;
    //load from mongo
    activityDao.findAllActivities(documents => {
        documents.forEach(document => {
            let activity = activityLoader(document);
            this.activities.push(activity);
            if(activity.id >= maxActivityId) {
                maxActivityId = activity.id;
            }
        });
        this.nextActivityId = maxActivityId + 1;
        this.sort();
    });
    // let configService = this.app.get("configService");
    // configService.findConfigByKey(HOT_ACTIVITY_CONFIG_KEY, config =>{
    //     if(!!config) {
    //         this.activityHotId = parseInt(config.value) || 0;
    //     }
    // });
};

ActivityService.prototype.getAllActivities = function () {
    return this.activities;
};

ActivityService.prototype.getSerializeActivities = function () {
    let serializeActivities = [];
    for(let activity of this.activities) {
        serializeActivities.push(activity.toJSON());
    }
    return serializeActivities;
};

ActivityService.prototype.getActivityById = function (id) {
    for(let activity of this.activities) {
        if(id === activity.id) {
            return activity;
        }
    }
    return null;
};

ActivityService.prototype.updateActivityUrl = function (id, url, callback) {
    let activityDao = this.app.get("activityDao");
    if(!this.contains(id)) {
        callback(null);
        return;
    }
    for(let activity of this.activities) {
        if(id === activity.id) {
            activityDao.updateUrl(id, url, result => {
                if(!result || result.result.ok != 1) {
                    logger.info(`updateActivityUrl error. document null`);
                    callback(null);
                    return;
                }
                activity.url = url;
                callback(activity);
            });
        }
    }
};

ActivityService.prototype.updateActivityPriority = function (id, priority, callback) {
    let activityDao = this.app.get("activityDao");
    if(!this.contains(id)) {
        callback(null);
        return;
    }
    for(let activity of this.activities) {
        if(id === activity.id) {
            activityDao.updatePriority(id, priority, result => {
                if(!result || result.result.ok != 1) {
                    logger.info(`updateActivityPrioritys error. document null`);
                    callback(null);
                    return;
                }
                activity.priority = priority;
                this.sort();
                callback(activity);
            });
        }
    }
};

ActivityService.prototype.updateActivity = function (id, title, priority, url, isHot, startTime, endTime, callback) {
    let activityDao = this.app.get("activityDao");
    let configService = this.app.get("configService");

    if(!this.contains(id)) {
        callback(null);
        return;
    }
    for(let activity of this.activities) {
        if(id === activity.id) {
            activityDao.update(id, title, priority, url, startTime, endTime, result => {
                if(!result || result.result.ok != 1) {
                    logger.info(`updateActivity error. result null`);
                    callback(null);
                    return;
                }
                activity.title = title;
                activity.priority = priority;
                activity.url = url;
                activity.isHot = isHot;
                activity.startTime = startTime;
                activity.endTime = endTime;
                this.sort();
                callback(activity);
                // change hot activity
                if(isHot) {
                    configService.upsertConfigValue(HOT_ACTIVITY_CONFIG_KEY, activity.id.toString(), config => {
                        if(!config) {
                            logger.info(`update config error. result null. config key:${HOT_ACTIVITY_CONFIG_KEY}`);
                            return;
                        }
                        // this.activityHotId = activity.id;
                    });
                }
            });
        }
    }
};

ActivityService.prototype.addActivity = function (title, priority, url, isHot, startTime, endTime, callback) {
    let activityDao = this.app.get("activityDao");
    let configService = this.app.get("configService");
    let activity = activityCreator(this.nextActivityId, title, priority, url, isHot, startTime, endTime);
    this.nextActivityId ++;
    activityDao.insertOne(activity.toBSON(), result => {
        if(!result || result.result.ok != 1) {
            logger.info(`addActivity error. result empty`);
            callback(null);
            return;
        }
        this.activities.push(activity);
        this.sort();
        callback(activity);
        //change hot activity
        if(isHot) {
            configService.upsertConfigValue(HOT_ACTIVITY_CONFIG_KEY, activity.id.toString(), config => {
                if(!config) {
                    logger.info(`update config error. result null. config key:${HOT_ACTIVITY_CONFIG_KEY}`);
                    return;
                }
                // this.activityHotId = activity.id;
            });
        }
    });
};

ActivityService.prototype.deleteActivityById = function (id, callback) {
    let activityDao = this.app.get("activityDao");
    let configService = this.app.get("configService");
    activityDao.deleteById(id, result => {
        if(!result || result.ok != 1) {
            logger.info(`deleteActivityById error. id empty`);
            callback(null);
            return;
        }
        let activities = [];
        for(let activity of this.activities) {
            if(activity.id !== id) {
                activities.push(activity);
            }
        }
        this.activities = activities;
        this.sort();
        callback(id);
        //change hot activity
        if(configService.contains(HOT_ACTIVITY_CONFIG_KEY) &&
            parseInt(configService.getEnableConfigValueByKey(HOT_ACTIVITY_CONFIG_KEY)) == id) {
            configService.updateConfigValue(HOT_ACTIVITY_CONFIG_KEY, "0", config => {
                if(!config) {
                    logger.info(`update config error. result null. config key:${HOT_ACTIVITY_CONFIG_KEY}`);
                    return;
                }
                // this.activityHotId = 0;
            });
        }
    });
};

ActivityService.prototype.getEffectActivityJSON = function () {
    let configService = this.app.get("configService");
    let activityHotId = configService.contains(HOT_ACTIVITY_CONFIG_KEY) ?  parseInt(configService.getEnableConfigValueByKey(HOT_ACTIVITY_CONFIG_KEY)) : 0;
    let serializeActivities = [];
    let now = DateUtil.nowMS();
    this.activities.forEach(activity => {
        if(now > activity.startTime && now < activity.endTime) {
            activity.isHot = activityHotId === activity.id;
            serializeActivities.push(activity.toJSON());
        }
    });
    return serializeActivities;
};

ActivityService.prototype.toJSON = function () {
    let configService = this.app.get("configService");
    let activityHotId = configService.contains(HOT_ACTIVITY_CONFIG_KEY) ?  parseInt(configService.getEnableConfigValueByKey(HOT_ACTIVITY_CONFIG_KEY)) : 0;
    let serializeActivities = [];
    this.activities.forEach(activity => {
        activity.isHot = activityHotId === activity.id;
        serializeActivities.push(activity.toJSON());
    });
    return serializeActivities;
};

ActivityService.prototype.contains = function (id) {
    for(let activity of this.activities) {
        if(activity.id === id) {
            return true;
        }
    }
    return false;
};

ActivityService.prototype.sort = function () {
    this.activities.sort(function (s1, s2) {
        if(s1.priority < s2.priority) {
            return -1;
        }else if(s1.priority > s2.priority) {
            return 1;
        }else{
            return s1.id < s2.id ? 1 : -1;
        }
    });
};

module.exports.create = function (app) {
    return new ActivityService(app);
};
